//
//  CQMantleSerialization.m
//  YZStock
//
//  Created by fenchol on 15/7/9.
//  Copyright (c) 2015年 fenchol. All rights reserved.
//

#import "YZMantleSerialization.h"
#import "Mantle.h"
#import "NSError+YZM.h"
#import "YZGeneralResultModel.h"
#import "YZRequestURLs.h"
#import "YZMLoginResultModel.h"
#import "YZGeneralResultModel.h"

@implementation YZMantleSerialization

- (id)responseObjectForResponse:(NSURLResponse *)response
                           data:(NSData *)data
                          error:(NSError *__autoreleasing *)error
{
#warning remove error process in  CQNetworkManager
    id responseObject = [super responseObjectForResponse: response data: data error: error];
    if (*error != nil) {
        return nil;
    }
    else if (responseObject == nil)
    {
        *error = [NSError yz_errorWithBadResponse];
        return nil;
    }
    
//#ifdef DEBUG_MODE
    NSLog(@"response.URL = %@", response.URL);
    NSLog(@"responseObject = %@", responseObject);
//#endif
    
    NSString *relativePath = response.URL.relativePath;
    if ([relativePath hasPrefix:@"/"]) {
        relativePath = [relativePath substringFromIndex: 1];
    }
    if ([relativePath isEqualToString: URL_FOR_LOGIN]) {
        id object = [MTLJSONAdapter modelOfClass: [YZMLoginResultModel class] fromJSONDictionary: responseObject error: error];
        return object;
    }
    
    //top levelClass
    YZGeneralResultModel *topModel = [MTLJSONAdapter modelOfClass: [YZGeneralResultModel class] fromJSONDictionary: responseObject error: error];
    if (topModel.data) {
        Class modelClass = [self modelClassForResonse: response];
        if (modelClass) {
            if ([modelClass respondsToSelector: @selector(yz_transFormWithData:error:)]) {
                topModel.data = [modelClass yz_transFormWithData: topModel.data error: error];
            }
            else if ([topModel.data isKindOfClass: [NSArray class]]) {
                NSArray *array = [MTLJSONAdapter modelsOfClass: modelClass fromJSONArray: topModel.data error: error];
                if (array.count > 0) {
                    topModel.data  = array;
                }
            }
            else
            {
                id mantleObject = [MTLJSONAdapter modelOfClass: modelClass fromJSONDictionary: topModel.data error: error];
                if (mantleObject) {
                    topModel.data = mantleObject;
                }
            }
        }
    }
    return topModel;
}

- (void)setURLModelMap:(NSDictionary *)URLModelMap
{
    NSMutableDictionary *actualMap = [NSMutableDictionary dictionary];
    NSArray *array = [URLModelMap allKeys];
    for (NSString *keyString in array) {
        NSInteger queryIndex = [keyString rangeOfString: @"?"].location;
        if (queryIndex != NSNotFound) {
            NSString *quary = [keyString substringFromIndex: queryIndex+1];
            NSArray *params = [quary componentsSeparatedByString: @"&"];
            NSSet *paramSet = [NSSet setWithArray: params];
            NSString *classStr = URLModelMap[keyString];
            NSDictionary *dict = @{CQPARAMSETKEY: paramSet, CQPARAYCLASSKEY: classStr};
            
            NSString *urlPath = [keyString substringToIndex: queryIndex];
            NSMutableArray *mapArray = actualMap[urlPath];
            if (mapArray == nil) {
                mapArray = [NSMutableArray array];
                actualMap[urlPath] = mapArray;
            }
            else if ([mapArray isKindOfClass:[NSString class]])
            {
                NSString *className = (NSString *)mapArray;
                mapArray = [NSMutableArray array];
                NSDictionary *noQureyDict = @{CQPARAYCLASSKEY: className};
                [mapArray addObject: noQureyDict];
                actualMap[urlPath] = mapArray;

            }
            [mapArray addObject: dict];
        }
        else
        {
            NSString *className = actualMap[keyString];
            if (className == nil || [className isKindOfClass:[NSString class]]) {
                actualMap[keyString] = URLModelMap[keyString];
            }
            else
            {
                NSMutableArray *mapArray = (NSMutableArray *)className;
                NSDictionary *noQureyDict = @{CQPARAYCLASSKEY: className};
                [mapArray addObject: noQureyDict];
            }
        }
        
    }
    _URLModelMap = actualMap;
}

- (Class)modelClassForResonse: (NSURLResponse *)response
{
    NSString *relativePath = response.URL.relativePath;
    id obj = self.URLModelMap[relativePath];
    if (obj == nil && [relativePath hasPrefix:@"/"]) {
        relativePath = [relativePath substringFromIndex: 1];
        obj = self.URLModelMap[relativePath];
    }
    if ([obj isKindOfClass: [NSString class]]) {
        return NSClassFromString(obj);
    }
    else //if ([obj isKindOfClass: [NSMutableArray class]])
    {
        NSArray *paramArray = obj;
        if (response.URL.query.length > 0) {
            NSArray *queryArray = [response.URL.query componentsSeparatedByString: @"&"];
            NSSet *paramSet = [NSSet setWithArray: queryArray];
            for (NSDictionary *dict in paramArray) {
                NSString *comparedSet = dict[CQPARAMSETKEY];
                if (comparedSet.length >0 && [paramSet containsObject:comparedSet]) {
                    
                    id result = dict[CQPARAYCLASSKEY];
                    if ([[result class] isSubclassOfClass:[NSString class]]) {
                        
                        return NSClassFromString(dict[CQPARAYCLASSKEY]);
                    }else{
                        
                        //二重匹配
                        NSArray *resultArray = result;
                        
                        NSMutableSet *restParamSet = [NSMutableSet setWithSet:paramSet];
                        [restParamSet removeObject:comparedSet];
                        
                        for (NSDictionary *dict2 in resultArray) {
                            
                            NSString *comparedSet2 = dict2[CQPARAMSETKEY];
                            if (comparedSet2.length >0 && [restParamSet containsObject:comparedSet2]) {
                                
                                return NSClassFromString(dict2[CQPARAYCLASSKEY]);
                            }
                        }
                        
                    }
                    
                }
            }
        }
        
        for (NSDictionary *dict in paramArray) {
            if (dict[CQPARAMSETKEY] == nil) {
                return NSClassFromString(dict[CQPARAYCLASSKEY]);
            }
        }
    }
    return nil;
}

@end
